package controller;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model.Extensions;

import org.ini4j.Ini;
import org.ini4j.InvalidFileFormatException;
import org.ini4j.Profile.Section;

import util.AuxExtensions;
import util.AuxExtensionsGlobals;
import util.Util;

/**
 * Servlet implementation class ExtensionsController
 */
public class ExtensionsController extends Controller {
	private static final long serialVersionUID = 1L;
	private final String KEY = "extensions";
    
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ExtensionsController() {
        super();
    }
    
    protected Class<?> getClassModel() {
    	return Extensions.class;
    }
    
    protected String getPathConfig() {
    	return Util.getPath(this.KEY);
    }
    
	private ArrayList<Extensions> listExtensions() {
    	
    	ArrayList<Extensions> lista = new ArrayList<Extensions>(0);
    	
		try {

			File f = new File(getPathConfig());

			BufferedReader in = new BufferedReader(new FileReader(f));

			Ini conf = new Ini();
			conf.load(in);
			
			Class<?> cls = getClassModel();

			Extensions extensions = new Extensions(); //Model.getModelInstance(cls);
			
			Field[] fields = cls.getDeclaredFields();

			Field field = null;
			
			String fieldName = null;
			
			Object fieldValue = null;
			
			String methodName = null;

			Method method = null;
			
			Section section = null;
			
			AuxExtensions aux = null;
			
			AuxExtensionsGlobals auxGlobals = null;
			
			String[] array = null;
			
			String auxAplicacao = null;
			
			// Varrendo todas as seções do arquivo
			for (String sectionName: conf.keySet()) {
				
				section = conf.get(sectionName);
				
				extensions = new Extensions();
				
				extensions.setId(sectionName);
				
				if (section.getName().matches("general")) {
					
					for (int i = 0; i < fields.length; i++) {
						
						field = fields[i];

						fieldName = field.getName();
						
						fieldValue = section.get(fieldName.toLowerCase().replace("_", ""));
						
						if (fieldValue != null) {
						
							methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
			
							method = cls.getMethod(methodName, field.getType());
							
							method.invoke(extensions, fieldValue);
						}
					}
					
				} else if (section.getName().matches("globals")) {
					
					for (String element: section.keySet()) {
					
						auxGlobals = new AuxExtensionsGlobals();
						
						auxGlobals.setChave(element);
						auxGlobals.setValor(section.get(element));
						
						extensions.getGlobals().add(auxGlobals);
					}
					
				} else {
					
					for (String element: section.getAll("exten")) {
						
						aux = new AuxExtensions();
						
						auxAplicacao = "";
						
						array = element.split(",");
						
						aux.setNumExtensao(array[0].replace(">", "").trim());
						aux.setPrioridade(Integer.parseInt(array[1]));
						
						// O 3o parâmetro pode conter vírgulas, então ele será quebrado em posições do array.
						// Para resolver isto, a partir da 3a posição fazemos um "for" para pegar todas as
						// posições seguintes.
						auxAplicacao = array[2];
						
						for (int i = 3; i < array.length; i++) {
							auxAplicacao += "," + array[i];
						}
						aux.setAplicacao(auxAplicacao);
						
						extensions.getLinhas().add(aux);
					}
				}
				
				lista.add(extensions);
	    	}

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidFileFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return lista;
    }
    
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
		RequestDispatcher rd = request.getRequestDispatcher("extensions.jsp");
		
		String act = request.getParameter("act") == null ? "" : request.getParameter("act");
		
		if (act.matches("create")) {
			this.create(request, response);
			
			request.setAttribute("act", "create");
			
		} else if (act.matches("retrieve")) {
			this.retrieve(request, response);
			
			request.setAttribute("act", "update");
			
		} else if (act.matches("update")) {
			this.update(request, response);
			
			request.setAttribute("act", "create");
			
		} else if (act.matches("delete")) {
			this.delete(request, response);
			
			request.setAttribute("act", "create");
			
		} else {
			
			request.setAttribute("act", "create");
		}
		
		ArrayList<Extensions> lista = listExtensions();
		
		request.setAttribute("lista", lista);
		
		rd.forward(request, response);
	}

}
